import { APlugin, TSelectRanage } from '../types/common.interface';
import { TableDatas } from '../cors/table-datas';
import { Injectable, PluginInjectable } from '../decorators/inject';
import { Select } from '../cors/select';
import { ExecuteRecord } from '../cors/execute-record';
import { MergeCommand } from '../commands/merge-command';
import { UnmergeCommand } from '../commands/unmerge-command';
import { Hook } from '../cors/hook';
import { RenderTrigger } from '../cors/render-trigger';
import { MergeCell } from '../cors/merge-cell';
import { MergeMapSubscriber } from 'rxjs/internal/operators/mergeMap';
@Injectable()
@PluginInjectable('MergeCellPlugin')
export class MergeCellPlugin extends APlugin {
    public canMerge: boolean = false;
    public canUnmerge: boolean = false;
    constructor(
        protected datas: TableDatas,
        protected select: Select,
        protected executeRecord: ExecuteRecord,
        protected hook: Hook,
        protected render: RenderTrigger,
        protected mergeCell: MergeCell
    ) {
        super();
    }
    public merge(range: TSelectRanage = this.select.selected) {
        let command = new MergeCommand(this.datas, range, this.render);
        this.executeRecord.execute(command);
    }
    public unmerge(range: TSelectRanage = this.select.selected) {
        let command = new UnmergeCommand(this.datas, range, this.select);
        this.executeRecord.execute(command);
        this.select.checkSelected();
    }
    public init() {
        this.hook.afterSelect.add((range) => {
            this.changeMergeStatus(range);
        });
        this.hook.afterCommandExcute.add(() => {
            this.changeMergeStatus(this.select.selected);
        });
    }
    protected changeMergeStatus(range: TRange) {
        if(range == null) {
            this.canMerge = false;
            this.canUnmerge = false;
        } else {
            if(range.col === -1 || range.row === -1) {
                let mergeInfo = this.mergeCell.getMerge(range.row, range.col);
                if(mergeInfo && mergeInfo.colspan === range.colspan && mergeInfo.rowspan === range.rowspan) {
                    this.canUnmerge = true;
                    this.canMerge = false;
                } else {
                    this.canMerge = true;
                    this.canUnmerge = false;
                }
            } else {
                if(range.rowspan != 1 || range.colspan != 1) {
                    let merge = this.mergeCell.getMerge(range.row, range.col);
                    if(merge && merge.row === range.row && merge.col === range.col && merge.rowspan === range.rowspan && merge.colspan === range.colspan) {
                        this.canMerge = false;
                    } else {
                        this.canMerge = true;
                    }
                } else {
                    this.canMerge = false;
                }
                for(let i = range.row; i < range.row + range.rowspan; i++) {
                    for(let j = range.col; j < range.col + range.colspan; j++) {
                        let merge = this.mergeCell.getMerge(i, j);
                        if(merge !== null) {
                            this.canUnmerge = true;
                            return;
                        }
                    }
                }
                this.canUnmerge = false;
            }
        }
    }
    public destroy() {

    }
}